package de.lighti.starcraft.bwapi;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Logger;

import de.lighti.starcraft.model.StarcraftBot;

public class Bwapi3_7_4 extends BWAPI {
    private final static Logger LOGGER = Logger.getLogger( Bwapi3_7_4.class.getName() );

    /**
     * Writes out a BWAPI 3.7.4 ini file using the information stored in this class
     * 
     * @param bwapi
     *            default values from server
     * @param location
     *            Absolute file path to bwapi.ini
     * @param thisBot
     *            The bot running on this machine
     * @param settings
     *            Client Settings
     * @param otherBot
     *            The other bot playing in this game
     * @param iD
     *            The Game ID number
     * @param isHost 
     * @throws IOException
     *             with file write problems
     */
    @Override
    public void writeIni( File location, StarcraftBot thisBot, StarcraftBot otherBot, int iD, boolean isHost ) throws IOException {
        BufferedWriter BWINI = null;
        final String n = System.lineSeparator();
        try {
            BWINI = new BufferedWriter( new FileWriter( location ) );

            BWINI.append( ";BWAPI written by Tournament Manager" + n + n );

            BWINI.append( "[ai]" + n );
            BWINI.append( "; Paths and revisions for AI" + n );
            BWINI.append( ";   - Use commas to specify AI for multiple instances." + n );
            BWINI.append( ";   - If there are more instances than the amount of " + n );
            BWINI.append( ";         DLLs specified, then the last entry is used." + n );
            BWINI.append( ";   - Use a colon to forcefully load the revision specified." + n );
            BWINI.append( ";   - Example: SomeAI.dll:3400, SecondInstance.dll, ThirdInstance.dll" + n );
            BWINI.append( "ai     = bwapi-data\\AI\\" + thisBot.getName() + ".dll" + n );
            BWINI.append( "ai_dbg = bwapi-data\\AI\\" + thisBot.getName() + ".dll" + n + n );

            BWINI.append( "; Used only for tournaments" + n );
            BWINI.append( "; Tournaments can only be run in RELEASE mode" + n );
            BWINI.append( "tournament =" + tournament + n + n );

            BWINI.append( "[auto_menu]" + n );
            BWINI.append( "; auto_menu = OFF | SINGLE_PLAYER | LAN | BATTLE_NET" + n );
            BWINI.append( "; for replays, just set the map to the path of the replay file" + n );
            BWINI.append( "auto_menu = " + auto_menu + n + n );

            BWINI.append( "; pause_dbg = ON | OFF" + n );
            BWINI.append( "; This specifies if auto_menu will pause until a debugger is attached to the process." + n );
            BWINI.append( "; Only works in DEBUG mode." + n );
            BWINI.append( "pause_dbg = " + pause_dbg + n + n );

            BWINI.append( "; lan_mode = Same as the text that appears in the multiplayer connection list" + n );
            BWINI.append( ";            Examples: Local Area Network (UDP), Local PC, Direct IP" + n );
            BWINI.append( "lan_mode = " + lan_mode + n + n );

            BWINI.append( "; auto_restart = ON | OFF" + n );
            BWINI.append( "; if ON, BWAPI will automate through the end of match screen and start the next match" + n );
            BWINI.append( "; if OFF, BWAPI will pause at the end of match screen until you manually click OK," + n );
            BWINI.append( "; and then BWAPI resume menu automation and start the next match" + n );
            BWINI.append( "auto_restart = " + auto_restart + n + n );

            BWINI.append( "; map = path to map relative to Starcraft folder, i.e. map = maps\\(2)Boxer.scm" + n );
            BWINI.append( "; leaving this field blank will join a game instead of creating it" + n );
            BWINI.append( "; The filename(NOT the path) can also contain wildcards, example: maps\\(?)*.sc?" + n );
            BWINI.append( "; A ? is a wildcard for a single character and * is a wildcard for a string of characters" + n );
            BWINI.append( "map = " + (isHost ? map : "") + "\n" + n );

            BWINI.append( "; game = name of the game to join" + n );
            BWINI.append( ";	i.e., game = BWAPI" + n );
            BWINI.append( ";	will join the game called \"BWAPI\"" + n );
            BWINI.append( ";	If the game does not exist and the \"map\" entry is not blank, then the game will be created instead" + n );
            BWINI.append( ";	If this entry is blank, then it will follow the rules of the \"map\" entry" + n );
            BWINI.append( "game = game" + iD + n + n );

            BWINI.append( "; mapiteration =  RANDOM | SEQUENCE" + n );
            BWINI.append( "; type of iteration that will be done on a map name with a wildcard" + n );
            BWINI.append( "mapiteration = " + mapiteration + n + n );

            BWINI.append( "; race = Terran | Protoss | Zerg | Random" + n );
            BWINI.append( "race = " + thisBot.getRace() + n + n );

            BWINI.append( "; enemy_count = 1-7, for 1v1 games, set enemy_count = 1" + n );
            BWINI.append( "; only used in single player games" + n );
            BWINI.append( "enemy_count = " + enemy_count + n + n );

            BWINI.append( "; enemy_race = Terran | Protoss | Zerg | Random | RandomTP | RandomTZ | RandomPZ" + n );
            BWINI.append( "; only used in single player games" + n );
            BWINI.append( "enemy_race = " + enemy_race + n + n );

            BWINI.append( "; enemy_race_# = Default" + n );
            BWINI.append( "; Values for enemy_race are acceptable, Default will use the value specified in enemy_race" + n );
            BWINI.append( "enemy_race_1 = " + enemy_race_1 + n );
            BWINI.append( "enemy_race_2 = " + enemy_race_2 + n );
            BWINI.append( "enemy_race_3 = " + enemy_race_3 + n );
            BWINI.append( "enemy_race_4 = " + enemy_race_4 + n );
            BWINI.append( "enemy_race_5 = " + enemy_race_5 + n );
            BWINI.append( "enemy_race_6 = " + enemy_race_6 + n );
            BWINI.append( "enemy_race_7 = " + enemy_race_7 + n );

            BWINI.append( ";game_type = TOP_VS_BOTTOM | MELEE | FREE_FOR_ALL | ONE_ON_ONE | USE_MAP_SETTINGS | CAPTURE_THE_FLAG" + n );
            BWINI.append( ";           | GREED | SLAUGHTER | SUDDEN_DEATH | TEAM_MELEE | TEAM_FREE_FOR_ALL | TEAM_CAPTURE_THE_FLAG" + n );
            BWINI.append( "game_type = " + game_type + n + n );

            BWINI.append( "; save_replay = path to save replay to" + n );
            BWINI.append( "; Accepts all environment variables including custom variables. See wiki for more info." + n );
            BWINI.append( "save_replay = " + "maps\\replays\\bwapi\\" + thisBot.getName() + "\\" + String.format( "%03d", iD ) + "-" + thisBot.getName()
                            + "_vs_" + otherBot.getName() + ".rep" + n + n );

            BWINI.append( "; wait_for_min_players = #" + n );
            BWINI.append( "; # of players to wait for in a network game before starting." + n );
            BWINI.append( "; This includes the BWAPI player. The game will start immediately when it is full." + n );
//            BWINI.append( "wait_for_min_players = " + wait_for_min_players + n + n );
            LOGGER.warning( "Harcoded \"wait_for_min_players = 2;\"" );
            BWINI.append( "wait_for_min_players = " + 2 + n + n );

            BWINI.append( "; wait_for_max_players = #" + n );
            BWINI.append( "; Start immediately when the game has reached # players." + n );
            BWINI.append( "; This includes the BWAPI player. The game will start immediately when it is full." + n );
//            BWINI.append( "wait_for_max_players = " + wait_for_max_players + n + n );
            BWINI.append( "wait_for_max_players = " + 2 + n + n );
            LOGGER.warning( "Harcoded \"wait_for_max_players = 2;\"" );

            BWINI.append( "; wait_for_time = #" + n );
            BWINI.append( "; The time in milliseconds (ms) to wait after the game has met the min_players requirement." + n );
            BWINI.append( "; The game will start immediately when it is full." + n );
            BWINI.append( "wait_for_time = " + wait_for_time + n + n );

            BWINI.append( "[config]" + n );
            BWINI.append( "; holiday = ON | OFF" + n );
            BWINI.append( "; This will apply special easter eggs to the game when it comes time for a holiday." + n );
            BWINI.append( "holiday = " + holiday + n + n );

            BWINI.append( "; show_warnings = YES | NO" + n );
            BWINI.append( "; Setting this to NO will disable startup Message Boxes, but also disable options that" + n );
            BWINI.append( "; assist in revision choice decisions." + n );
            BWINI.append( "show_warnings = " + show_warnings + n + n );

            BWINI.append( "; shared_memory = ON | OFF" + n );
            BWINI.append( "; This is specifically used to disable shared memory (BWAPI Server) in the Windows Emulator \"WINE\"" + n );
            BWINI.append( "; Setting this to OFF will disable the BWAPI Server, default is ON" + n );
            BWINI.append( "shared_memory = " + shared_memory + "\n" + n );

            BWINI.append( "[window]" + n );
            BWINI.append( "; These values are saved automatically when you move, resize, or toggle windowed mode" + n );

            BWINI.append( "; windowed = ON | OFF" + n );
            BWINI.append( "; This causes BWAPI to enter windowed mode when it is injected." + n );
            BWINI.append( "windowed = " + windowed + "\n" + n );

            BWINI.append( "; left, top" + n );
            BWINI.append( "; Determines the position of the window" + n );
            BWINI.append( "left = " + left + "\n" + n );
            BWINI.append( "top  = " + top + "\n" + n );

            BWINI.append( "; width, height" + n );
            BWINI.append( "; Determines the width and height of the client area and not the window itself" + n );
            BWINI.append( "width  = " + width + n + n );
            BWINI.append( "height = " + height + n + n );

            BWINI.append( "[starcraft]" + n );
            BWINI.append( "; Game sound engine = ON | OFF" + n );
            BWINI.append( "sound = " + sound + "" + n );
            BWINI.append( "; Screenshot format = gif | pcx | tga | bmp" + n );
            BWINI.append( "screenshots = " + screenshots + "\n" + n );

            BWINI.append( "[paths]" + n );
            BWINI.append( "log_path = " + log_path + "" + n );
        }
        finally {
            if (BWINI != null) {
                BWINI.close();
            }
        }
    }
}
